package com.scc.service.impl;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.scc.mapper.MessageMapper;
import com.scc.mapper.UserMapper;
import com.scc.pojo.*;
import com.scc.service.UserService;
import com.scc.utils.JwtUtil;
import jakarta.servlet.http.HttpServletRequest;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
public class UserServiceImpl implements UserService {
    //注入mapper
    @Autowired
    private UserMapper userMapper;

    //注入消息聊天的mapper
    @Autowired
    private MessageMapper messageMapper;

    //获取http对象
    @Autowired
    HttpServletRequest httpServletRequest;

    //员工登录搜索操作
    @Override
    public Emp login(Emp emp) {
        Emp EMP = userMapper.login(emp);
        if (EMP != null) {
            //如果这个员工不为null->说明员工登录成功
            //修改员工的登录状态(根据这个员工对象的信息)
            userMapper.modifyEmpLoginStatus(EMP);
        }
        return EMP;
    }

    //员工登录成功后根据账号获取头像的信息
    @Override
    public Emp getEmpImageByAccount(String account) {
        //根据账号查询图片url
        return userMapper.getEmpImageByAccount(account);
    }

    //修改员工表的图片路径
    @Async
    @Override
    public void modifyEmpImage(String url, String account) {
        userMapper.modifyEmpImage(url,account);
    }

    //员工查询或者获取自己的考勤信息
    @Override
    public PageBean getEmpAttendanceMsgByAccount(Integer page, Integer pageSize, String account, Integer empAttendanceStatus, LocalDate start, LocalDate end) {
        List<Attendance> attendanceList = userMapper.getEmpAttendanceMsgByAccount(account,empAttendanceStatus,start,end);
        //转换集合
        PageInfo<Attendance> pageInfo = new PageInfo<>(attendanceList);
        //返回分页对象
        return new PageBean(pageInfo.getTotal(), pageInfo.getList());
    }

    //修改员工的考勤状态
    @Async
    @Override
    public void modifyEmpAttendanceStatus(Attendance attendance) {
        //如果员工是迟到或者考勤成功，要获取当前的时间
        if(attendance.getEmpAttendanceStatus()==1||attendance.getEmpAttendanceStatus()==4){
            //获取当前时间
            LocalDateTime now = LocalDateTime.now();
            //格式化时间
            DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            String dateTime = now.format(dateTimeFormatter);
            //转化为LocalDateTime
            LocalDateTime empAttendanceTime = LocalDateTime.parse(dateTime, dateTimeFormatter);
            attendance.setEmpAttendanceTime(empAttendanceTime);
            //修改对象的用户考勤时间
        }
        userMapper.modifyEmpAttendanceStatus(attendance);
    }

    //员工请假提交申请表单(添加操作)
    @Async
    @Override
    public void empApplyLeave(Leave leave) {
        userMapper.empApplyLeave(leave);
    }

    //员工请假信息表的获取
    @Override
    public PageBean getEmpApplyLeave(Integer page, Integer pageSize, String account, Integer approveStatus, String leaveType, LocalDate startDate, LocalDate endDate) {
        //分页参数
        PageHelper.startPage(page, pageSize);
        //查询要返回一个请假对象的集合
        List<Leave> empLeaveList = userMapper.getEmpApplyLeave(account,approveStatus,leaveType,startDate,endDate);
        PageInfo<Leave> pageInfo = new PageInfo<>(empLeaveList);
        return new PageBean(pageInfo.getTotal(), pageInfo.getList());
    }

    ///修改账号和姓名，全部表都要变
    //员工修改个人信息
    @Async
    @Override
    public void modifyEmpMegByAccount(Emp emp, Integer id) {
        ///先获取以前员工的账号
        Emp oldEmp = userMapper.getOldEmpMsg(id);
        ///员工信息表改变根据旧的账号
        userMapper.modifyEmpMegByAccount(emp,id);
        ///员工考勤表改变根据旧账号对应的id
        userMapper.modifyAttendanceByAccount(emp.getAccount(),emp.getName(),oldEmp.getAccount());
        ///员工请假表改变根据旧的账号
        userMapper.modifyLeaveByAccount(emp.getAccount(),emp.getName(),oldEmp.getAccount());
        ///员工离职表改变根据旧的账号
        userMapper.modifyResignByAccount(emp.getAccount(),emp.getName(),oldEmp.getAccount());
        ///员工团建活动报名表要改变根据旧的账号
        userMapper.modifyTeamBuildingActByAccount(emp.getAccount(),emp.getName(),oldEmp.getAccount());
        ///员工培训活动报名表要改变根据旧的账号
        userMapper.modifyTrainingActByAccount(emp.getAccount(),emp.getName(),oldEmp.getAccount());
        ///员工工资信息账号也要改变
        userMapper.modifyEmpSalaryByAccount(emp.getAccount(),oldEmp.getAccount());
        ///员工在线信息表也要改变根据账号在员工修改信息的时候
        userMapper.modifyEmpOnlineByAccount(emp.getAccount(),emp.getName(),oldEmp.getAccount());
        ///员工操作日志表也要更改
        userMapper.modifyEmpOperationLogByAccount(emp.getAccount(),emp.getName(),oldEmp.getAccount());
    }

    //员工离职申请
    @Async
    @Override
    public void empResignApply(Resign emp) {
        userMapper.empResignApply(emp);
    }

    //员工离职申请表信息的获取或者查询
    @Override
    public PageBean getEmpResignMsgByAccount(Integer page, Integer pageSize, String account, Integer approveStatus, LocalDate startDate, LocalDate endDate) {
        PageHelper.startPage(page, pageSize);
        List<Resign> empResignMsgList = userMapper.getEmpResignMsgByAccount(account,approveStatus,startDate,endDate);
        PageInfo<Resign> pageInfo = new PageInfo<>(empResignMsgList);
        return new PageBean(pageInfo.getTotal(), pageInfo.getList());
    }

    //员工获取或查询培训活动信息
    @Override
    public PageBean getTrainingActivityMsg(Integer page, Integer pageSize, String account, String trainingName, Integer activityStatus, LocalDate start, LocalDate end) {
        PageHelper.startPage(page, pageSize);
        List<TrainingActivity> trainingActivityList = userMapper.getTrainingActivityMsg(page,pageSize,trainingName,activityStatus,start,end);
        //要对该查询用户的报名情况对培训活动对象的报名状态进行改变，在前端页面展示
        EmpTrainingActivity empTrainingActivity;
        for (TrainingActivity trainingActivity : trainingActivityList) {
            /*
            根据活动对应的id和账号在员工培训活动报名表进行查找
            对象为null->报名状态就是未报名，为2
            对象不为null->报名状态就是已报名，为1
            */
            ///活动id
            int id = trainingActivity.getId();
            //每次都创建一个新的对象
            empTrainingActivity = userMapper.selectEmpTrainingAct(id,account);
            //不为null 报名了
            if(empTrainingActivity!=null){
                trainingActivity.setRegistrationStatus(1);
            }else{
                //为null 没报名
                trainingActivity.setRegistrationStatus(2);
            }
        }
        PageInfo<TrainingActivity> pageInfo = new PageInfo<>(trainingActivityList);
        return new PageBean(pageInfo.getTotal(), pageInfo.getList());
    }

    ///员工培训活动的报名操作
    @Async
    @SneakyThrows
    @Override
    public void empRegistrationActivity(String empTrainingActivity) {
        //转化json
        ObjectMapper objectMapper = new ObjectMapper();
        JsonNode jsonNode = objectMapper.readTree(empTrainingActivity);
        //将json对象转化为员工培训活动报名表对象
        EmpTrainingActivity empTrainingActivityMsg = new EmpTrainingActivity();
        empTrainingActivityMsg.setId(jsonNode.get("id").asInt());
        empTrainingActivityMsg.setTrainingName(jsonNode.get("trainingName").asText());
        empTrainingActivityMsg.setName(jsonNode.get("name").asText());
        empTrainingActivityMsg.setGender(jsonNode.get("gender").asInt());
        empTrainingActivityMsg.setAccount(jsonNode.get("account").asText());
        String RegistrationTime = jsonNode.get("registrationTime").asText();
        LocalDateTime registrationTime = LocalDateTime.parse(RegistrationTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        empTrainingActivityMsg.setRegistrationTime(registrationTime);
        //报名成功之后，培训活动信息表的实际参加人数要加一
        userMapper.empRegistrationActivity(empTrainingActivityMsg);
        //根据员工报名培训活动的id来对培训活动信息表进行添加
        userMapper.addTrainingActivityActualAttendance(empTrainingActivityMsg.getId());
    }

    ///获取员工培训活动表该员工的信息根据id,账号，培训活动名称
    @Override
    public EmpTrainingActivity getEmpTrainingActivityMsg(Integer id, String account, String trainingName) {
        return userMapper.getEmpTrainingActivityMsg(id,account,trainingName);
    }

    //对员工活动报名表的删除根据id,账号
    @Override
    @Async
    public void empDeleteTrainingActivityMsg(Integer id, String account) {
        userMapper.empDeleteTrainingActivityMsg(id,account);
        //员工取消报名之后，培训活动信息表的实际参加人数要减一
        userMapper.reduceTrainingActivityActualAttendance(id);
    }

    //员工修改密码
    @Override
    @Async
    public void modifyPassword(Emp emp) {
        userMapper.modifyPassword(emp);
    }

    //员工获取或者查找团建活动信息表
    @Override
    public PageBean getTeamBuildingActivities(Integer page, Integer pageSize, String teamBuildingName, Integer activityStatus, LocalDate start, LocalDate end, String account) {
        PageHelper.startPage(page, pageSize);
        List<TeamBuildingActivities> teamBuildingActivitiesList = userMapper.getTeamBuildingActivities(teamBuildingName,activityStatus,start,end);
        /*
        根据当前该用户的账号是否报名该团建活动来确定该用户的活动参与状态
        遍历集合对每一个团建活动对象进行修改
        */
        for (TeamBuildingActivities teamBuildingActivity : teamBuildingActivitiesList) {
            //获取id
            int id = teamBuildingActivity.getId();
            //根据账号和id来查找员工团建活动对象
            EmpTeamBuildingActivityRegistration ETBAR = userMapper.getRegistrationMsg(id,account);
            //对象不为null -> 该活动已经报名 活动状态变为1
            if(ETBAR!=null){
                teamBuildingActivity.setRegistrationStatus(1);
            }else{
                //对象为null -> 未报名 活动状态2
                teamBuildingActivity.setRegistrationStatus(2);
            }
        }
        PageInfo<TeamBuildingActivities> pageInfo = new PageInfo<>(teamBuildingActivitiesList);
        return new PageBean(pageInfo.getTotal(), pageInfo.getList());
    }

    //员工报名团建活动
    @Async
    @SneakyThrows
    @Override
    public void empRegistrationTeamBuildingAct(String teamBuildingActivity) {
        //解析json
        ObjectMapper objectMapper = new ObjectMapper();
        JsonNode jsonNode = objectMapper.readTree(teamBuildingActivity);
        //设置员工团建报名对象
        EmpTeamBuildingActivityRegistration teamBuildingActivityMsg = new EmpTeamBuildingActivityRegistration();
        //赋值
        teamBuildingActivityMsg.setId(jsonNode.get("id").asInt());
        teamBuildingActivityMsg.setTeamBuildingName(jsonNode.get("teamBuildingName").asText());
        teamBuildingActivityMsg.setName(jsonNode.get("name").asText());
        teamBuildingActivityMsg.setGender(jsonNode.get("gender").asInt());
        teamBuildingActivityMsg.setAccount(jsonNode.get("account").asText());
        String RegistrationTime = jsonNode.get("registrationTime").asText();
        //格式化时间
        LocalDateTime registrationTime = LocalDateTime.parse(RegistrationTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        teamBuildingActivityMsg.setRegistrationTime(registrationTime);
        //添加员工团建活动报名表操作
        userMapper.addEmpTeamBuildingActMsg(teamBuildingActivityMsg);
        //如果报名成功，团建活动报名表实际参加人数应该加1,根据团建活动对应的id
        userMapper.addActualAttendanceNumber(teamBuildingActivityMsg.getId());
    }

    //获取团建活动的详细对象更具账号id
    @Override
    public EmpTeamBuildingActivityRegistration empTeamBuildingActivityMsg(Integer id, String account) {
        return userMapper.getEmpTeamBuildingActMsg(id,account);
    }

    //员工取消团建活动的报名操作
    @Async
    @Override
    public void empDeleteTeamBuildingActivity(Integer id, String account) {
        //员工活动报名表删除了之后
        userMapper.empDeleteTeamBuildingActivity(id,account);
        //团建活动的报名表也要删除
        userMapper.reduceTeamBuildingAct(id);
    }

    //员工获取自己的工资信息
    @Override
    public PageBean getEmpSalaryByAccount(String account, Integer page, Integer pageSize, LocalDate startDate, LocalDate endDate) {
        PageHelper.startPage(page, pageSize);
        //查询员工工资表根据账号
        List<EmpSalary> empSalaryList = userMapper.selectEmpSalaryByAccount(account,startDate,endDate);
        PageInfo<EmpSalary> pageInfo = new PageInfo<>(empSalaryList);
        return new PageBean(pageInfo.getTotal(), pageInfo.getList());
    }

    //员工登录下线之后，记录下线时间
    @SneakyThrows
    @Override
    public void insertEmpOnlineMsg(String empOnlineMsg) {
        //解析json
        ObjectMapper objectMapper = new ObjectMapper();
        JsonNode jsonNode = objectMapper.readTree(empOnlineMsg);
        //解析节点
        String account = jsonNode.get("account").asText();
        String onlineEndTime = jsonNode.get("onlineEndTime").asText();
        String onlineStartTime = jsonNode.get("onlineStartTime").asText();
        String loginDate = jsonNode.get("loginDate").asText();
        ///转化时间
        LocalDate LoginDate = LocalDate.parse(loginDate, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        LocalDateTime OnlineStartTime = LocalDateTime.parse(onlineStartTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        LocalDateTime OnlineEndTime = LocalDateTime.parse(onlineEndTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        ///获取姓名
        String name = userMapper.getNameByAccount(account);
        ///获取ip
        String ipAddress = httpServletRequest.getRemoteAddr();
        ///获取用户在线时长(分钟)
        Duration duration = Duration.between(OnlineStartTime, OnlineEndTime);
        int totalOnlineMin = (int) duration.toMinutes();
        userMapper.insertEmpEndOnlineMsg(name,account,LoginDate,OnlineEndTime,OnlineStartTime,totalOnlineMin,ipAddress);
        //下线之后要把在线状态改为离线
        userMapper.updateEmpStatus(account);
    }

    //员工根据账号查询好友
    @Override
    public List<Emp> searchFriendByAccount(String account) {
        List<Emp> empList = userMapper.selectEmpMsgByAccount(account);
        //获取自己的id
        String jwt = httpServletRequest.getHeader("token");
        //解析jwt
        Map<String, Object> claims = JwtUtil.parseJwt(jwt);
        Integer empId = (Integer) claims.get("id");
        //遍历集合获取查找的好友的id,返回一个申请状态
        for (Emp emp : empList) {
            //多表查询两个表，如果两个表都有数据不为null说明两个是好友
            List<FriendshipApplication> friendshipApplicationList = userMapper.selectApplyStatus(empId);
            if(!friendshipApplicationList.isEmpty()){
                emp.setApplyStatus(2);
            }else{
                List<Integer> applyStatusList = userMapper.selectApplyStatusById(empId,emp.getId());
                for (Integer applyStatus : applyStatusList) {
                    if(applyStatus==0){
                        emp.setApplyStatus(applyStatus);
                        break;
                    }
                }
            }
        }
        return empList;
    }

    //员工申请好友添加
    @SneakyThrows
    @Override
    public void insertApplyFriendMsg(String applyFriendMsg) {
        //解析json
        ObjectMapper objectMapper = new ObjectMapper();
        JsonNode jsonNode = objectMapper.readTree(applyFriendMsg);
        //获取节点
        int applyId = jsonNode.get("applyId").asInt();
        int receiveId = jsonNode.get("receiveId").asInt();
        String ApplyTime = jsonNode.get("applyTime").asText();
        LocalDateTime applyTime = LocalDateTime.parse(ApplyTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        //好友添加对象
        FriendshipApplication friendshipApplication = new FriendshipApplication();
        //添加对象信息
        friendshipApplication.setApplyId(applyId);
        friendshipApplication.setReceiveId(receiveId);
        friendshipApplication.setApplyTime(applyTime);
        userMapper.insertApplyFriendMsg(friendshipApplication);
    }

    //员工查看自己的好友申请
    @Override
    public List<Emp> selectFriendApply(Integer receiveId) {
        //获取自己被申请的对应的申请人的员工id
        List<FriendshipApplication> friendshipApplications = userMapper.selectFriendApplyId(receiveId);
        //准备一个员工集合
        List<Emp> empList = new ArrayList<>();
        //遍历好友申请的集合
        for (FriendshipApplication friendshipApplication : friendshipApplications) {
            //根据申请人的id获取员工信息
            Emp emp = userMapper.getApplyEmpMsg(friendshipApplication.getApplyId());
            //设置申请状态，放在历史状态还是申请状态,申请状态和好友申请状态一致
            emp.setApplyStatus(friendshipApplication.getApplyStatus());
            emp.setApplyTime(friendshipApplication.getApplyTime());
            empList.add(emp);
        }
        return empList;
    }

    //员工查询我的好友申请
    @Override
    public List<Emp> selectApply(Integer applyId) {
        //根据自己的id去获取被申请好友的接收方的id
        List<FriendshipApplication> friendshipApplications = userMapper.selectApplyId(applyId);
        //准备一个接收方好友的员工信息集合
        List<Emp> empList = new ArrayList<>();
        //遍历集合获取我想添加好友的信息
        for (FriendshipApplication friendshipApplication : friendshipApplications) {
            //获取我想添加好友的信息
            Emp emp = userMapper.getApplyEmpMsg(friendshipApplication.getReceiveId());
            //设置申请状态
            emp.setApplyStatus(friendshipApplication.getApplyStatus());
            emp.setApplyTime(friendshipApplication.getApplyTime());
            empList.add(emp);
        }
        return empList;
    }

    //员工同意好友操作
    @SneakyThrows
    @Override
    public void insertFriendRelationShip(String applyMsg) {
        //解析json获取申请人的id和接收方的id
        ObjectMapper objectMapper = new ObjectMapper();
        JsonNode jsonNode = objectMapper.readTree(applyMsg);
        //解析节点
        int applyId = jsonNode.get("applyId").asInt();
        int receiveId = jsonNode.get("receiveId").asInt();
        //获取时间
        String addTime = jsonNode.get("addTime").asText();
        String applyTime = jsonNode.get("applyTime").asText();
        //转化时间
        LocalDateTime AddTime = LocalDateTime.parse(addTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        LocalDateTime ApplyTime = LocalDateTime.parse(applyTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        //同意的申请状态
        int applyStatus = 2;
        //先在好友申请表把申请状态改为已同意
        userMapper.modifyApplyStatus(applyId,receiveId,ApplyTime,applyStatus);
        /*
        接着添加好友关系表
        有两层关系，所以要添加两次
        */
        //申请人的好友关系
        userMapper.insertFriendRelationship(applyId,receiveId,AddTime);
        //接收人的好友关系
        userMapper.insertFriendRelationship(receiveId,applyId,AddTime);
    }

    //员工拒绝好友申请
    @SneakyThrows
    @Override
    public void refuseApply(String applyMsg) {
        //解析json
        ObjectMapper objectMapper = new ObjectMapper();
        JsonNode jsonNode = objectMapper.readTree(applyMsg);
        //解析json
        int applyId = jsonNode.get("applyId").asInt();
        int receiveId = jsonNode.get("receiveId").asInt();
        String applyTime = jsonNode.get("applyTime").asText();
        LocalDateTime ApplyTime = LocalDateTime.parse(applyTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        //获取申请状态 不同意的申请状态
        int applyStatus = 1;
        //修改申请状态
        userMapper.modifyApplyStatus(applyId,receiveId, ApplyTime, applyStatus);
    }

    //员工获取自己的好友列表
    @Override
    public List<Emp> selectFriendMsg(Integer empId) {
        //多表查询
        return userMapper.selectFriendMsg(empId);
    }

    //员工删除好友，删除好友关系表
    @Override
    public void deleteFriendListById(Integer applyId, Integer friendId) {
        //要把两个关系都删除
        userMapper.deleteFriendRelation(applyId,friendId);
        userMapper.deleteFriendRelation(friendId,applyId);
        //聊天列表也要删除
        messageMapper.deleteMessageListByApplyId(applyId);
    }
}
